Skip to content

[VW-319] Adding teamplay Fleet Work Order Integration#152

Open
markglose-bc wants to merge 1 commit into
mainfrom
VW-319
Open

[VW-319] Adding teamplay Fleet Work Order Integration#152
markglose-bc wants to merge 1 commit into
mainfrom
VW-319

Conversation

@markglose-bc

@markglose-bc markglose-bc commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Adding new Integration workflow for teamplay Fleet

to replicate, add the following Work Order integration

URL: https://fleet.siemens-healthineers.com/rest/v1/activities?tz=-05%3A00&statusFilter=1
Auth: Header
Header Name: Cookie
Header Value: XSRF-TOKEN={value}; subTenantClientId={value}; JSESSIONID={value};

image

Summary by CodeRabbit

  • New Features

    • Added support for work orders across the app, including a new Work Orders area, mapping to external IDs, and a new maintenance ticket category.
    • Added a new REST integration option for syncing work-order data from supported external systems.
    • Expanded sync and upload flows so work-order items can be imported and updated through integrations.
  • Bug Fixes

    • Improved handling of dates, statuses, and source details when processing incoming work-order activity data.

@markglose-bc markglose-bc requested review from 0xcad and perrydev17 July 8, 2026 18:39
@markglose-bc markglose-bc self-assigned this Jul 8, 2026
@vercel

vercel Bot commented Jul 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
viper Ignored Ignored Preview Jul 8, 2026 6:43pm
viper-demo Ignored Ignored Jul 8, 2026 6:43pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 83f2ef2e-43b9-406a-9d1f-c2ff50bdaabc

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • ✅ Review completed - (🔄 Check again to review again)
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch VW-319

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bulk of the teamplay Fleet to VIPER work order mapping code

map: (raw, url) =>
mapFleetActivities(raw, { offset: deriveOffsetFromUrl(url) }),
},
];

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where we can expand easily to other partner integrations with similar workflows.

@markglose-bc markglose-bc marked this pull request as ready for review July 8, 2026 18:44

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/features/tracking/server/fleet-mapper.ts (1)

1-6: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add server-only directive to enforce server/client boundary.

This file lives in src/features/tracking/server/ and uses kebab-case utility naming, making it a server utility file per the project's naming convention. It should be marked with server-only to prevent accidental client-side imports.

As per coding guidelines: "Mark server utility files with 'server-only' and client components with 'use client' directive to enforce clear server/client boundaries."

🔧 Add server-only directive
+import "server-only";
 import { z } from "zod";
 import {
   NotificationChannel,
   TicketCategory,
   TicketStatus,
 } from "`@/generated/prisma`";
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/tracking/server/fleet-mapper.ts` around lines 1 - 6, Add the
server-only boundary marker to this server utility module so it cannot be
imported from client code. Update the top of the file in fleet-mapper (the
module that imports zod and Prisma enums) to include the server-only directive
before other imports, keeping the rest of the server-side logic unchanged.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/inngest/functions/sync-integrations.ts`:
- Around line 225-236: The hostname lookup in selectRestMapper is too permissive
because host.includes(m.hostMatch) can match lookalike domains and choose the
wrong REST_MAPPER. Update selectRestMapper to use exact host matching or safe
subdomain-suffix matching against integration.integrationUri’s parsed hostname,
and keep the resourceType check intact so only the intended adapter is returned.

---

Nitpick comments:
In `@src/features/tracking/server/fleet-mapper.ts`:
- Around line 1-6: Add the server-only boundary marker to this server utility
module so it cannot be imported from client code. Update the top of the file in
fleet-mapper (the module that imports zod and Prisma enums) to include the
server-only directive before other imports, keeping the rest of the server-side
logic unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9f255588-9774-4020-8798-7cbe80ce871c

📥 Commits

Reviewing files that changed from the base of the PR and between 8a6406d and 0b09df2.

📒 Files selected for processing (12)
  • prisma/migrations/20260708073706_work_order_integration_squashed/migration.sql
  • prisma/schema.prisma
  • src/features/api-key-connectors/components/connectors-layout.tsx
  • src/features/integrations/components/integrations.tsx
  • src/features/integrations/types.ts
  • src/features/tag-colors/components/tag-colors.tsx
  • src/features/tracking/components/ticket-detail/shared.tsx
  • src/features/tracking/server/fleet-mapper.test.ts
  • src/features/tracking/server/fleet-mapper.ts
  • src/features/tracking/server/routers.ts
  • src/features/tracking/types.ts
  • src/inngest/functions/sync-integrations.ts

Comment on lines +225 to +236
function selectRestMapper(integration: IntegrationWithStringDates) {
let host = "";
try {
host = new URL(integration.integrationUri).hostname.toLowerCase();
} catch {
// Malformed URL → no adapter matches; the caller throws a clear error.
}
return REST_MAPPERS.find(
(m) =>
m.resourceType === integration.resourceType && host.includes(m.hostMatch),
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

selectRestMapper substring match can select the wrong adapter for lookalike hostnames.

host.includes(m.hostMatch) matches any hostname containing the substring, so a URL like https://fleet.siemens-healthineers.com.evil.com/ would incorrectly select the Fleet adapter. Use exact host or subdomain suffix matching instead.

🔒 Proposed fix for hostname matching
   return REST_MAPPERS.find(
     (m) =>
-      m.resourceType === integration.resourceType && host.includes(m.hostMatch),
+      m.resourceType === integration.resourceType &&
+      (host === m.hostMatch || host.endsWith(`.${m.hostMatch}`)),
   );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function selectRestMapper(integration: IntegrationWithStringDates) {
let host = "";
try {
host = new URL(integration.integrationUri).hostname.toLowerCase();
} catch {
// Malformed URL → no adapter matches; the caller throws a clear error.
}
return REST_MAPPERS.find(
(m) =>
m.resourceType === integration.resourceType && host.includes(m.hostMatch),
);
}
function selectRestMapper(integration: IntegrationWithStringDates) {
let host = "";
try {
host = new URL(integration.integrationUri).hostname.toLowerCase();
} catch {
// Malformed URL → no adapter matches; the caller throws a clear error.
}
return REST_MAPPERS.find(
(m) =>
m.resourceType === integration.resourceType &&
(host === m.hostMatch || host.endsWith(`.${m.hostMatch}`)),
);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/inngest/functions/sync-integrations.ts` around lines 225 - 236, The
hostname lookup in selectRestMapper is too permissive because
host.includes(m.hostMatch) can match lookalike domains and choose the wrong
REST_MAPPER. Update selectRestMapper to use exact host matching or safe
subdomain-suffix matching against integration.integrationUri’s parsed hostname,
and keep the resourceType check intact so only the intended adapter is returned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants